from django.db import DatabaseError
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.filters import OrderingFilter
from rest_framework.generics import GenericAPIView, RetrieveAPIView, ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, CreateModelMixin
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAdminUser, AllowAny, IsAuthenticated, IsAuthenticatedOrReadOnly
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ReadOnlyModelViewSet

from booktest.models import BookInfo
from booktest.serializers import BookInfoSerializer


# class BookListView(APIView):
#     """使用APIView查询所有图书接口"""
#     def get(self, request):
#         # 获取查询集
#         books = BookInfo.objects.all()
#         # 创建序列化器进行序列化
#         serializer = BookInfoSerializer(books, many=True)
#         # 响应
#         return Response(serializer.data)

#
# class BookDetailView(GenericAPIView):
#     """使用GenericAPIView书籍的详情视图"""
#     # 指定查询集(指定数据的来源)
#     queryset = BookInfo.objects.all()
#     # 指定序列化器(将过来的数据转换或校验通过哪个序列化器)
#     serializer_class = BookInfoSerializer
#
#     def get(self, request, pk):
#         """查询单一图书"""
#         # 获取单一模型对象
#         book = self.get_object()
#         # 获取序列化器对象
#         serializer = self.get_serializer(book)
#         # 响应
#         return Response(serializer.data)

#
# class BookListView(GenericAPIView):
#     """书籍的列表视图"""
#     # 指定查询集(指定数据的来源)
#     queryset = BookInfo.objects.all()
#     # 指定序列化器(将过来的数据转换或校验通过哪个序列化器)
#     serializer_class = BookInfoSerializer
#
#     def get(self, request):
#         """查询所有图书"""
#         # 获取查询集
#         books = self.get_queryset()
#         # 获取序列化器对象
#         serializer = self.get_serializer(books, many=True)
#         # 响应
#         return Response(serializer.data)


# class BookListView(ListModelMixin, CreateModelMixin, GenericAPIView):
#     # ListModelMixin，列表视图扩展类
#     queryset = BookInfo.objects.all()
#     serializer_class = BookInfoSerializer
#
#     def get(self, request):
#         return self.list(request)
#
#     def post(self, request):
#         return self.create(request)
# #
# class BookDetailView(RetrieveModelMixin, GenericAPIView):
#     """书籍的详情视图"""
#     # 指定查询集
#     queryset = BookInfo.objects.all()
#     # 指定序列化器
#     serializer_class = BookInfoSerializer
#
#     def get(self, request, pk):
#         # 查询单一图书
#         return self.retrieve(request)
#
# class BookDetailView(RetrieveAPIView):
#     """书籍的详情视图"""
#     # 指定查询集
#     queryset = BookInfo.objects.all()
#     # 指定序列化器
#     serializer_class = BookInfoSerializer
#
#
# class BookListView(ListAPIView):
#     """书籍的列表视图"""
#     # 指定查询集
#     queryset = BookInfo.objects.all()
#     # 指定序列化器
#     serializer_class = BookInfoSerializer


# class BookInfoViewSet(viewsets.ViewSet):
#     """基本视图集"""
#
#     def list(self, request):
#         # 获取查询集
#         books = BookInfo.objects.all()
#         # 获取序列化器对象
#         serializer = BookInfoSerializer(books, many=True)
#         # 响应
#         return Response(serializer.data)
#
#     def retrieve(self, request, pk):
#
#         try:
#             books = BookInfo.objects.get(id=pk)
#         except BookInfo.DoesNotExist:
#             return Response(status=status.HTTP_404_NOT_FOUND)
#         serializer = BookInfoSerializer(books)
#         return Response(serializer.data)


class StandardPageNumberPagination(PageNumberPagination):
    """自定义Pagination类进行分页"""
    page_size = 6  # 每页显示的条数
    page_query_param = 'page'  # 前端发送的页数关键字名,默认为page
    page_size_query_param = 'page_size'  # 前端发送的每页数目关键字名，默认为None
    max_page_size = 10  # 前端最多能设置的每页数量


class BookInfoViewSet(ReadOnlyModelViewSet):
    """查询的视图集"""

    # 指定视图访问的权限
    permission_classes = [IsAdminUser]  # 只有登录用户才能访问此视图中的所有接口

    throttle_classes = (UserRateThrottle,)

    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    # 指定可以过滤的字段
    # 127.0.0.1:8000/books/?btitle=西游记
    # 127.0.0.1:8000/books/?id=2
    filter_fields = ['btitle', 'id']

    # 指定过滤后端为排序
    filter_backends = [OrderingFilter]
    # 指定可以进行排序的字段
    # 127.0.0.1:8000/books/?ordering=-bread
    ordering_filter = ['id', 'bread', 'bpub_date']

    # pagination_class  指定分页的类
    # 127.0.0.1:8000/books/?page=1&page_size=2
    pagination_class = StandardPageNumberPagination

    # detail为False 表示路径名格式应该为 books/latest/
    @action(methods=['get'], detail=False)
    def latest(self, request):
        """返回最新的图书信息"""
        raise DatabaseError()

        book = BookInfo.objects.latest('id')
        serializer = self.get_serializer(book)
        return Response(serializer.data)

    # detail为True，表示路径名格式应该为 books/{pk}/read/
    @action(methods=['put'], detail=True)
    def read(self, request, pk):
        """修改图书的阅读量数据"""
        book = self.get_object()
        book.bread = request.data.get('bread')
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)
